#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <MQTTClient.h>
 
#define ADDRESS     "tcp://192.168.23.125:1883"
#define CLIENTID    "90ec8ca7-124f-4ece-8288-4c4a12cf1941" 
#define TOPIC_PULL       "remote_to_local"   //订阅主题
#define TOPIC_PUSH       "local_to_remote"   //发布主题
#define PAYLOAD     "Hello World!"
#define QOS         1
#define TIMEOUT     10000L

static MQTTClient_message pubmsg = MQTTClient_message_initializer;
 
//客户端消息发布回调
void delivered(void *context, MQTTClient_deliveryToken dt)
{
    printf("消息发送完成\n");
}
 
//数据到达客户端回调
int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    printf("收到远程的消息：%s\n",message->payload);
    //释放内存
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    //发送成功返回1
    return 1;
}
 
//连接断开回调
void connlost(void *context, char *cause)
{
    printf("连接断开，原因%s\n",cause);
}
 
int main(int argc, char* argv[])
{
    MQTTClient client;
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    int rc;
    
    //1.创建客户端（参数3：服务器是否存储数据还是直接发给订阅，参数4：回调函数参数）
    if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID,
        MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to create client, return code %d\n", rc);
        //rc是失败原因
        rc = EXIT_FAILURE;
        goto exit;
    }
    
    //2.创建回调函数（参数2：回调参数，参数后面：三个回调函数名）
    if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to set callbacks, return code %d\n", rc);
        rc = EXIT_FAILURE;
        goto destroy_exit;
    }
    //连接到服务器
    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to connect, return code %d\n", rc);
        rc = EXIT_FAILURE;
        goto destroy_exit;
    }
 
    printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
           "Press Q<Enter> to quit\n\n", TOPIC_PULL, CLIENTID, QOS);
    //订阅主题
    if ((rc = MQTTClient_subscribe(client, TOPIC_PULL, QOS)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to subscribe, return code %d\n", rc);
        rc = EXIT_FAILURE;
    }
    else
    {
        int ch;
        //阻塞式获取控制台输入的第一个字符q
        do
        {
                ch = getchar();
        } while (ch!='Q' && ch != 'q');
        //取消订阅
        if ((rc = MQTTClient_unsubscribe(client, TOPIC_PULL)) != MQTTCLIENT_SUCCESS)
        {
                printf("Failed to unsubscribe, return code %d\n", rc);
                rc = EXIT_FAILURE;
        }
}

    pubmsg.payload = PAYLOAD;
    pubmsg.payloadlen = (int)strlen(PAYLOAD);
    pubmsg.qos = QOS;
    //发布消息
    if ((rc = MQTTClient_publishMessage(client, TOPIC_PUSH, &pubmsg, NULL)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to publish message, return code %d\n", rc);
        rc = EXIT_FAILURE;
    }
    //断开连接
    if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to disconnect, return code %d\n", rc);
        rc = EXIT_FAILURE;
}
return rc;

destroy_exit:
//销毁客户端
    MQTTClient_destroy(&client);
exit:
    return rc;
}
